#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <iostream>
#include <string>
#include <cstring>
#include <cerrno>

void handle_request(int client_socket) {
    char buffer[1024];
    int bytes_received = recv(client_socket, buffer, sizeof(buffer), 0);
    if (bytes_received < 0) {
        std::cerr << "recv error: " << strerror(errno) << std::endl;
        close(client_socket);
        return;
    }

    std::string request_data(buffer, bytes_received);
    std::cout << "Received Request:\n" << request_data << std::endl;

    // 解析请求行
    size_t first_line_end = request_data.find("\r\n");
    std::string request_line = request_data.substr(0, first_line_end);
    size_t path_start = request_line.find(' ') + 1;
    size_t path_end = request_line.find(' ', path_start);
    std::string path = request_line.substr(path_start, path_end - path_start);

    int status_code;
    std::string response_body;

    if (path == "/") {
        status_code = 200;
        response_body = "<h1>Welcome to Linux Web Server</h1>";
    } else if (path == "/about") {
        status_code = 200;
        response_body = "<h1>About this Linux Server</h1>";
    } else {
        status_code = 404;
        response_body = "<h1>404 Not Found</h1>";
    }

    std::string status_line = "HTTP/1.1 " + std::to_string(status_code) + 
                            (status_code == 200 ? " OK" : " Not Found") + "\r\n";
    std::string headers = "Content-Type: text/html\r\n";
    headers += "Content-Length: " + std::to_string(response_body.size()) + "\r\n";
    headers += "Connection: close\r\n\r\n";

    std::string response = status_line + headers + response_body;

    if (send(client_socket, response.c_str(), response.size(), 0) < 0) {
        std::cerr << "send error: " << strerror(errno) << std::endl;
    }

    close(client_socket);
}

void run_server() {
    int server_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (server_socket < 0) {
        std::cerr << "socket creation failed: " << strerror(errno) << std::endl;
        return;
    }

    // 设置地址重用
    int enable = 1;
    if (setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable))) {
        std::cerr << "setsockopt failed: " << strerror(errno) << std::endl;
        close(server_socket);
        return;
    }

    sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(8080);

    if (bind(server_socket, (sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        std::cerr << "bind failed: " << strerror(errno) << std::endl;
        close(server_socket);
        return;
    }

    if (listen(server_socket, 5) < 0) {
        std::cerr << "listen failed: " << strerror(errno) << std::endl;
        close(server_socket);
        return;
    }

    std::cout << "Server running on http://0.0.0.0:8080" << std::endl;

    while (true) {
        sockaddr_in client_addr;
        socklen_t client_addr_len = sizeof(client_addr);
        int client_socket = accept(server_socket, 
                                 (sockaddr*)&client_addr,
                                 &client_addr_len);
        if (client_socket < 0) {
            std::cerr << "accept failed: " << strerror(errno) << std::endl;
            continue;
        }

        char client_ip[INET_ADDRSTRLEN];
        inet_ntop(AF_INET, &client_addr.sin_addr, client_ip, INET_ADDRSTRLEN);
        std::cout << "Connected by " << client_ip << ":" 
                 << ntohs(client_addr.sin_port) << std::endl;

        handle_request(client_socket);
    }

    close(server_socket);
}

int main() {
    run_server();
    return 0;
}


/*
要在linux环境下运行
g++ -std=c++11 socket_simple.cpp -o server -pthread

./server
*/